import base64
import json
import os
import random
import re
from django import http
from django.http import JsonResponse
from django.shortcuts import render
from django.views import View
from django_redis import get_redis_connection
from apps.users.models import User
from apps.verifications.views import SMSCodeView
from utils.secret import SecretOauth
# 展示修改密码页面


class FindPassword(View):
    def get(self,request):
        return render(request,'find_password.html')
# 第一步 校验图片验证码


class AccountsUsername(View):
    def get(self, request,username):
        # 接受参数
        image_code =request.GET.get('image_code')
        uuid =request.GET.get('image_code_id')
        # 校验参数
        if not all([username, image_code,uuid]):
            return http.HttpResponseForbidden('缺少必传参数')
        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
            return http.HttpResponseForbidden('请输入5-20个字符的用户名')
        try:
            user = User.objects.get(username=username)
            mobile = user.mobile
        except:
            return JsonResponse({"status": 5004})
        # 校验图形验证码
            # 2 校验图形验证码如果正确发送验证码, 不正确直接返回
            # 2.1 根据uuid 去redis数据库查询 图片验证码
        image_redis_client = get_redis_connection('verify_image_code')
        redis_img_code = image_redis_client.get('img_%s' % uuid)
        # # 如果有值 删除redis服务器上的图形验证码
        image_redis_client.delete('img_%s' % uuid)
        # 和前端传过来的进行做对比
        # 千万注意: 在redis取出来的是 bytes 类型不能直接做对比 decode()
        # 返回Json数据

        if redis_img_code.decode().lower() != image_code.lower():
            return JsonResponse({'status': '5001',})
        # # 生成token存到数据库
        token = generat_csrf()
        token_client = get_redis_connection("token")
        token_client.setex('token_%s' % mobile, 600, token)
        # 加密token
        access_token = SecretOauth().dumps(token)
        # # 加密的字符串(是为了保证三次提交的唯一性, 从下次请求的时候必须校验access_token的准确性)
        return JsonResponse({"status": 5000,"mobile": mobile,"access_token":access_token})
# 第二部生成短信验证码


class SmsCodes(View):
    def get(self,request,mobile):
        # 接受参数
        token = request.GET.get('access_token')
        if not all([mobile, token]):
            return http.HttpResponseForbidden('缺少必传参数')
        access_token = SecretOauth().loads(token)
        try:
            # 链接数据库取出token
            token_client = get_redis_connection("token")
            redis_token = token_client.get('token_%s' % mobile).decode()
        except:
            return JsonResponse({"status": 5001, "message": 'token有误'})
        # 校验参数
        if access_token != redis_token:
            return JsonResponse({"status": 5001, "message": 'token有误'})
        # 3 生成短信验证码, redis - 存储 并设置过期时间
        sms_code = '%06d' % random.randint(0, 999999)
        sms_redis_client = get_redis_connection("sms_code")
        sms_redis_client.setex("sms_%s" % mobile, 300, sms_code)
        # 发短信--------容联运
        # 建立异步服务
        from celery_tasks.sms.tasks import send_sms_code_ccp
        send_sms_code_ccp.delay(mobile, sms_code)
        print('原始文件的短信码', sms_code)
        return JsonResponse({"status": 5000, "message": '短信验证码生成成功'})
# 检验短信验证码


class AccountsSmsCodes(View):
    def get(self,request,mobile):
        # 接受参数
        sms_code = request.GET.get('sms_code')

        user = request.user
        redis_mobile = user.mobile
        user_id = user.id
        # 校验参数
        if redis_mobile !=mobile:
            return JsonResponse({"status": 5004})
        # # 取数据
        redis_code_client = get_redis_connection("sms_code")
        redis_code = redis_code_client.get("sms_%s" % mobile)
        # 验证短信验证码是否正确;
        # 对比redis的值和前端的值
        if sms_code != redis_code.decode():
            return JsonResponse({"status": 5001})
        # 链接数据库取出token
        token_client = get_redis_connection("token")
        token = token_client.get('token_%s' % mobile).decode()
        access_token = SecretOauth().dumps(token)
        return JsonResponse({"status": 5000, "user_id":user_id,'access_token':access_token})
# 重置密码


class ResettingPassword(View):

    def post(self,request,user_id):
        # 接受参数
        json_dict = json.loads(request.body.decode())
        password = json_dict.get('password')
        password2 = json_dict.get('password2')
        token = json_dict.get('access_token')
        if not all([password, password2, token]):
            return http.HttpResponseForbidden('缺少必传参数')
        access_token = SecretOauth().loads(token)
        try:
            user = User.objects.get(id=user_id)
            mobile = user.mobile
        except:
            return JsonResponse({"status": 5002,'message':'user_id有误!'})
        try:
            # 链接数据库取出token
            token_client = get_redis_connection("token")
            redis_token = token_client.get('token_%s' % mobile).decode()
        except:
            return JsonResponse({"status": 5001, "message": 'token有误'})
        # 检验参数
        if access_token != redis_token:
            return JsonResponse({"status": 5001, 'message': 'token有误!'})
        if password != password2:
            return http.HttpResponseForbidden("两次输入密码不一致")
        # 修改密码  保存到数据库
        user.set_password(password)
        user.save()
        return JsonResponse({"status": 5000, 'message': '密码重置成功'})

# 生成 随机码

def generat_csrf():
    return bytes.decode(base64.b64encode(os.urandom(48)))